package adminIndexService

import (
	"time"

	adminDynamicFieldEntry "gitee.com/krio/ginc/example/internal/admin/dynamic/field/entry"

	"gitee.com/krio/ginc/example/core/exerr"
	"gitee.com/krio/ginc/example/core/lib/conf"
	exampleDtoApiPbAdminIndex "gitee.com/krio/ginc/example/dto/api/pb/admin/index"
	exampleDtoApiPbSsoUserLogin "gitee.com/krio/ginc/example/dto/api/pb/sso/user_login"
	adminConfigDao "gitee.com/krio/ginc/example/internal/admin/config/dao"
	adminConfigModel "gitee.com/krio/ginc/example/internal/admin/config/model"
	adminMenuDao "gitee.com/krio/ginc/example/internal/admin/menu/dao"
	adminMenuModel "gitee.com/krio/ginc/example/internal/admin/menu/model"
	adminUserAccountDao "gitee.com/krio/ginc/example/internal/admin/user/account/dao"
	adminUserAccountModel "gitee.com/krio/ginc/example/internal/admin/user/account/model"
	adminUserLoginLogDao "gitee.com/krio/ginc/example/internal/admin/user/login_log/dao"
	adminUserLoginLogModel "gitee.com/krio/ginc/example/internal/admin/user/login_log/model"
	commonEntry "gitee.com/krio/ginc/example/internal/common/entry/common"
	commonModel "gitee.com/krio/ginc/example/internal/common/model/common"
	ssoUserLoginService "gitee.com/krio/ginc/example/internal/sso/user_login/service"
	anyThor "gitee.com/krio/ginc/example/util/thor/any"
	userUtil "gitee.com/krio/ginc/example/util/user"
	"github.com/gin-gonic/gin"
)

// AdminLogin 登录
func AdminLogin(ctx *gin.Context, req *exampleDtoApiPbAdminIndex.AdminLoginReq) (*exampleDtoApiPbAdminIndex.AdminLoginResp, error) {
	dao := &adminUserAccountDao.AdminUserAccountDao{}
	userInfo, has, err := dao.UserDetailByInfo(ctx, &adminUserAccountModel.AdminUserAccount{
		UserAccount: req.LoginAccount,
	})
	if !has {
		return nil, exerr.UserNotFound
	}
	if err != nil {
		return nil, err
	}
	checkPwd, err := userUtil.EncryptPWD(req.LoginPassword)
	if err != nil {
		return nil, err
	}
	if userUtil.CheckPWD(userInfo.UserPwd, checkPwd) {
		return nil, exerr.UserPasswordErr
	}
	loginResp, err := ssoUserLoginService.UserLogin(ctx, &exampleDtoApiPbSsoUserLogin.UserLoginReq{
		LoginId:     userInfo.UserUuid,
		LoginDevice: ssoUserLoginService.ADMIN.ToString(),
	})
	if err != nil {
		return nil, err
	}
	data := &exampleDtoApiPbAdminIndex.AdminLoginResp{
		AccessToken: loginResp.Token,
		UserId:      userInfo.UserUuid,
		UserName:    userInfo.UserName,
		ExpireTime:  time.Now().Add(time.Duration(conf.C.Login.ExpiresTime) * time.Minute).Unix(),
	}

	loginLogDao := adminUserLoginLogDao.AdminUserLoginLogDao{}
	_, err = loginLogDao.UserLoginLogAdd(ctx, &adminUserLoginLogModel.AdminUserLoginLog{
		UserId:      userInfo.ID,
		UserName:    userInfo.UserName,
		UserToken:   loginResp.Token,
		LoginIp:     ctx.ClientIP(),
		LoginAgent:  ctx.GetHeader("User-Agent"),
		LoginResult: "success",
	})
	if err != nil {
		return nil, err
	}

	return data, nil
}

// AdminLogout 登出
func AdminLogout(ctx *gin.Context, req *exampleDtoApiPbAdminIndex.AdminLogoutReq) error {
	err := ssoUserLoginService.UserLogout(ctx, req.LoginToken)
	if err != nil {
		return err
	}
	return nil
}

// AdminIni 导航栏
func AdminIni(ctx *gin.Context, req *exampleDtoApiPbAdminIndex.AdminIniReq) (*exampleDtoApiPbAdminIndex.AdminIniResp, error) {

	dao := &adminConfigDao.AdminConfigDao{}
	one, exi, err := dao.ConfigDetailByInfo(ctx, &adminConfigModel.AdminConfig{
		Code:   "admin_home_config",
		Status: commonModel.DataNormal,
	})
	if err != nil {
		return nil, err
	}
	homeInfo := &exampleDtoApiPbAdminIndex.AdminIniInfo{
		Title: "首页",
		Href:  "/page/index/welcome.html?t=1",
	}
	logoInfo := &exampleDtoApiPbAdminIndex.AdminIniInfo{
		Title: homeInfo.Title,
		Image: "/images/favicon.ico",
	}
	if exi {
		homeInfo.Title = anyThor.AnyToString(one.MetaData["admin_home_title"])
		homeInfo.Href = anyThor.AnyToString(one.MetaData["admin_home_href"])
		logoInfo.Title = homeInfo.Title
		logoInfo.Image = anyThor.AnyToString(one.MetaData["admin_home_logo"])
	}

	menuDao := &adminMenuDao.AdminMenuDao{}
	list, total, err := menuDao.MenuList(ctx, &commonEntry.ListCommonReq{
		IsAll:    true,
		StatusIn: []int32{int32(commonModel.DataNormal)},
	})
	if err != nil {
		return nil, err
	}
	var (
		sortIdMap = make(map[int64]bool, total)
		sortMap   = make(map[int64][]*adminMenuModel.AdminMenu)
	)
	for _, v := range list {
		sortIdMap[v.ID] = true
	}
	for _, v := range list {
		if v.AfterId > 0 && sortIdMap[v.AfterId] {
			sortMap[v.AfterId] = append(sortMap[v.AfterId], v)
		} else {
			v.AfterId = 0
		}
	}
	var menuInfo []*exampleDtoApiPbAdminIndex.AdminIniInfo
	for _, v := range list {
		if v.AfterId > 0 {
			continue
		}
		menuInfo = append(menuInfo, formatDetail(v))
		if infos, ok := sortMap[v.ID]; ok {
			for _, vv := range infos {
				menuInfo = append(menuInfo, formatDetail(vv))
			}
		}
	}
	menuInfoTree := formatTree(menuInfo, 0)
	data := &exampleDtoApiPbAdminIndex.AdminIniResp{
		HomeInfo: homeInfo,
		LogoInfo: logoInfo,
		MenuInfo: []*exampleDtoApiPbAdminIndex.AdminIniInfo{
			{
				Title:  "常规管理",
				Icon:   "fa fa-address-book",
				Target: "_self",
				Child:  menuInfoTree,
			},
		},
	}
	return data, nil
}

func formatTree(list []*exampleDtoApiPbAdminIndex.AdminIniInfo, pid int64) []*exampleDtoApiPbAdminIndex.AdminIniInfo {
	var data []*exampleDtoApiPbAdminIndex.AdminIniInfo
	for _, v := range list {
		if v.Pid == pid {
			child := formatTree(list, v.Id)
			v.Child = child
			data = append(data, v)
		}
	}
	return data
}

func formatDetail(v *adminMenuModel.AdminMenu) *exampleDtoApiPbAdminIndex.AdminIniInfo {
	return &exampleDtoApiPbAdminIndex.AdminIniInfo{
		Id:     v.ID,
		Pid:    v.Pid,
		Title:  v.Title,
		Href:   v.Href,
		Icon:   v.Icon,
		Image:  v.Image,
		Target: v.Target,
		Child:  nil,
	}
}

// AdminPageInfo 页面配置信息
func AdminPageInfo(ctx *gin.Context, req *exampleDtoApiPbAdminIndex.AdminPageInfoReq) (*exampleDtoApiPbAdminIndex.AdminPageInfoResp, error) {
	dao := &adminConfigDao.AdminConfigDao{}
	one, exi, err := dao.ConfigDetailByInfo(ctx, &adminConfigModel.AdminConfig{
		Code:   "admin_page_config",
		Status: commonModel.DataNormal,
	})
	if err != nil {
		return nil, err
	}
	if !exi {
		return nil, nil
	}
	data := &exampleDtoApiPbAdminIndex.AdminPageInfoResp{
		AdminPageTitle:   anyThor.AnyToString(one.MetaData["admin_page_title"]),
		AdminPageKeyword: anyThor.AnyToString(one.MetaData["admin_page_keyword"]),
		AdminPageDesc:    anyThor.AnyToString(one.MetaData["admin_page_desc"]),
	}

	return data, nil
}

// AdminEnumList 枚举信息
func AdminEnumList(ctx *gin.Context, req *exampleDtoApiPbAdminIndex.AdminEnumListReq) (*exampleDtoApiPbAdminIndex.AdminEnumListResp, error) {
	var list []*exampleDtoApiPbAdminIndex.AdminEnumList
	for _, key := range req.Keys {
		var infos []*exampleDtoApiPbAdminIndex.AdminEnumInfo
		arr := adminDynamicFieldEntry.Get(key)
		for _, v := range arr {
			infos = append(infos, &exampleDtoApiPbAdminIndex.AdminEnumInfo{Name: v.Name, Val: v.Value})
		}
		list = append(list, &exampleDtoApiPbAdminIndex.AdminEnumList{
			Key:  key,
			Info: infos,
		})
	}
	return &exampleDtoApiPbAdminIndex.AdminEnumListResp{
		List: list,
	}, nil
}
